package com.jeeplus.modules.newtower.utils.newUtils;

import org.springframework.util.ObjectUtils;

/**
 * GB/T 36904-2018定义的ISO/IEC 7064的MOD 37,36算法
 * @Author cenminghao
 */
public class CheckDigitUtils {
    public static String countcheckBit(String data) {
        if (ObjectUtils.isEmpty(data)) {
            return "";
        }
        // 移除所有点号
        String cleaned = data.replaceAll("\\.", ""); // 移除所有点号

        int mod36 = 36;//公式里的模数，M
        int mod37 = 37;//公式里的M+1
        int Pj = mod36;//公式里的乘积，Pj，初始值=M
        int checkValue = 0;//校验位值
        //遍历字符串每一位
        for (int i = 0; i < cleaned.length(); i++) {
            char c = cleaned.charAt(i);
            // 转换字符到数值
            // 如果是数字字符（0-9），则用 c - '0' 得到其整数值；如果是大写字母（A-Z），则用 c - 'A' + 10 转换为10~35之间的数值。
            int value = Character.isDigit(c) ? c - '0' : (c - 'A' + 10);

            Pj += value;//乘积+字符值=中间和Sj
            Pj %= mod36;//Sj除以M后的余数=调整中间和
            Pj = Pj==0?mod36:Pj;//如果=0，则应替换为M
            Pj *= 2;//调整中间和*2
            Pj %= mod37;//Pj+1除以M+1的余数=下次计算值的乘积
//            System.out.println("Pj = " + Pj);

        }
        checkValue = mod37 - Pj;//要求Sn mod M = 1

        checkValue = (checkValue == 36) ? 0 : checkValue; // 36转为0

        String checkDigit;//校验位结果
        if (checkValue < 10) {
            checkDigit =  String.valueOf((char) ('0' + checkValue)); // 数字
        } else {
            checkDigit = String.valueOf((char) ('A' + checkValue - 10)); // 字母
        }
        return checkDigit;
    }


    /**
     * 主方法测试示例
     */
    public static void main(String[] args) {
        String input = "11100000000013338W002.11320482014138860P.201807250201.001";
        String checkDigit = countcheckBit(input);
        System.out.println("checkDigit = " + checkDigit);
    }
}
